//
// Created by xiaoma on 2/4/21.
//

#include <iostream>
#include <cassert>
#include "HiInteger.h"

static void verifyKlass(HiObject *lhs, HiObject *rhs, IntegerKlass *target) {
    assert(lhs->klass() == rhs->klass());
    auto l = (HiInteger *) lhs;
    auto r = (HiInteger *) rhs;
    assert(l && l->klass() == (Klass *) target);
    assert(r && r->klass() == (Klass *) target);
}

void IntegerKlass::print(HiObject *object) {
    auto obj = (HiInteger *) object;
    assert(obj->klass() == (Klass *) this);
    std::cout << obj->value() << std::endl;
}

HiObject *IntegerKlass::add(HiObject *lhs, HiObject *rhs) {
    verifyKlass(lhs, rhs, this);
    auto l = (HiInteger *) lhs;
    auto r = (HiInteger *) rhs;
    return new HiInteger(l->value() + r->value());
}


HiBool *IntegerKlass::less(HiObject *lhs, HiObject *rhs) {
    verifyKlass(lhs, rhs, this);
    auto l = (HiInteger *) lhs;
    auto r = (HiInteger *) rhs;
    return l->value() < r->value() ? Universe::True : Universe::False;
}

HiBool *IntegerKlass::lessEqual(HiObject *lhs, HiObject *rhs) {
    verifyKlass(lhs, rhs, this);
    auto l = (HiInteger *) lhs;
    auto r = (HiInteger *) rhs;
    return l->value() <= r->value() ? Universe::True : Universe::False;
}

HiBool *IntegerKlass::equal(HiObject *lhs, HiObject *rhs) {
    verifyKlass(lhs, rhs, this);
    auto l = (HiInteger *) lhs;
    auto r = (HiInteger *) rhs;
    return l->value() == r->value() ? Universe::True : Universe::False;
}

HiBool *IntegerKlass::notEqual(HiObject *lhs, HiObject *rhs) {
    verifyKlass(lhs, rhs, this);
    auto l = (HiInteger *) lhs;
    auto r = (HiInteger *) rhs;
    return l->value() != r->value() ? Universe::True : Universe::False;
}

HiBool *IntegerKlass::greater(HiObject *lhs, HiObject *rhs) {
    verifyKlass(lhs, rhs, this);
    auto l = (HiInteger *) lhs;
    auto r = (HiInteger *) rhs;
    return l->value() > r->value() ? Universe::True : Universe::False;
}

HiBool *IntegerKlass::greaterEqual(HiObject *lhs, HiObject *rhs) {
    verifyKlass(lhs, rhs, this);
    auto l = (HiInteger *) lhs;
    auto r = (HiInteger *) rhs;
    return l->value() >= r->value() ? Universe::True : Universe::False;
}